'use strict';

var assign = require('lodash/assign');

var entryFactory = require('../../../../factory/EntryFactory');

var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'),
    eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

function isAsyncBefore(bo) {
    return asyncCapableHelper.isAsyncBefore(bo);
}

function isAsyncAfter(bo) {
    return asyncCapableHelper.isAsyncAfter(bo);
}

function isExclusive(bo) {
    return asyncCapableHelper.isExclusive(bo);
}

function removeFailedJobRetryTimeCycle(bo, element) {
    return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
}

function canRemoveFailedJobRetryTimeCycle(element) {
    return !eventDefinitionHelper.getTimerEventDefinition(element);
}

module.exports = function (element, bpmnFactory, options, translate) {

    var getBusinessObject = options.getBusinessObject;

    var idPrefix = options.idPrefix || '',
        labelPrefix = options.labelPrefix || '';


    var asyncBeforeEntry = entryFactory.checkbox({
        id: idPrefix + 'asyncBefore',
        label: labelPrefix + translate('Asynchronous Before'),
        modelProperty: 'asyncBefore',

        get: function (element, node) {
            var bo = getBusinessObject(element);
            return {
                asyncBefore: isAsyncBefore(bo)
            };
        },

        set: function (element, values) {
            var bo = getBusinessObject(element);
            var asyncBefore = !!values.asyncBefore;

            var props = {
                'flowable:asyncBefore': asyncBefore,
                'flowable:async': false
            };

            var commands = [];
            if (!isAsyncAfter(bo) && !asyncBefore) {
                props = assign({'flowable:exclusive': true}, props);
                if (canRemoveFailedJobRetryTimeCycle(element)) {
                    commands.push(removeFailedJobRetryTimeCycle(bo, element));
                }
            }

            commands.push(cmdHelper.updateBusinessObject(element, bo, props));
            return commands;
        }
    });


    var asyncAfterEntry = entryFactory.checkbox({
        id: idPrefix + 'asyncAfter',
        label: labelPrefix + translate('Asynchronous After'),
        modelProperty: 'asyncAfter',

        get: function (element, node) {
            var bo = getBusinessObject(element);
            return {
                asyncAfter: isAsyncAfter(bo)
            };
        },

        set: function (element, values) {
            var bo = getBusinessObject(element);
            var asyncAfter = !!values.asyncAfter;

            var props = {
                'flowable:asyncAfter': asyncAfter
            };

            var commands = [];
            if (!isAsyncBefore(bo) && !asyncAfter) {
                props = assign({'flowable:exclusive': true}, props);
                if (canRemoveFailedJobRetryTimeCycle(element)) {
                    commands.push(removeFailedJobRetryTimeCycle(bo, element));
                }
            }

            commands.push(cmdHelper.updateBusinessObject(element, bo, props));
            return commands;
        }
    });


    var exclusiveEntry = entryFactory.checkbox({
        id: idPrefix + 'exclusive',
        label: labelPrefix + translate('Exclusive'),
        modelProperty: 'exclusive',

        get: function (element, node) {
            var bo = getBusinessObject(element);
            return {exclusive: isExclusive(bo)};
        },

        set: function (element, values) {
            var bo = getBusinessObject(element);
            return cmdHelper.updateBusinessObject(element, bo, {'flowable:exclusive': !!values.exclusive});
        },

        hidden: function (element) {
            var bo = getBusinessObject(element);
            return bo && !isAsyncAfter(bo) && !isAsyncBefore(bo);
        }
    });

    return [asyncBeforeEntry, asyncAfterEntry, exclusiveEntry];
};
